#include <iostream>
#include "book_service.h"
#include <time.h>

using namespace std;

int BookService::borrowBook(unsigned int bid,unsigned int uid)
{
    char acc_path[255] ={};
    sprintf(acc_path,"../data/book/%d.txt",bid);
    if( -1 == access(acc_path,F_OK))
    {
        return -4; //该书不存在
    }
    BookServiceData m;
    Book* book = m.load(bid);
    AccountData x;
    Account* acc = x.load(uid);
    
    if(acc == NULL)
    {
        return -5 ;//用户id错误
    }

    if(false == book->m_isShelf) return -1;  //未上架
    if(0 == book->m_amout) return -2;       //余量不足
    if(0 >= acc->m_money || DEPOSIT >= acc->m_deposit) return -3;  //余额不足，需要充值
    
    vector<Account::Reserve>::iterator it;
    for(it = acc->m_reserve.begin();it !=acc->m_reserve.end();it++)
    {
         time_t timep;
         struct tm *p;
         time(&timep);
         p=localtime(&timep); 
         time_t old = mktime(&it->m_time);
         time_t cur = mktime(p);
         unsigned int num = 0;
         num = cur - old;
         if(num > 60)
         {
            acc->m_reserve.erase(it);
            it = acc->m_reserve.begin();
         } 
    }
    BookServiceData n;
    n.save(*book);
    for(unsigned int i=0;i < acc->m_reserve.size();i++)
    {
        if( uid == acc->m_reserve.at(i).m_id)
        {
            if( book->m_amout  > i)
            {
                time_t timep;
                struct tm *p;
                time (&timep);
                p=localtime(&timep);
                struct tm tt = {};
                
                Record r(book->m_record.size()+1,book->m_name.c_str(),book->m_id,acc->m_name.c_str(),uid,*p,30,false,tt);
                
                acc->borrowBook(bid,30);
                
                book->m_amout = book->m_amout -1;
                book->addRecord(r);
                BookServiceData n;
                n.save(*book);
                return 0;   
            }
            else
            {
                return -2;    
            }
        }       
    }
    
    if(book->m_amout > acc->m_reserve.size())
    {
        
        time_t timep;
        struct tm *p;
        time (&timep);
        p=localtime(&timep);
        struct tm tt = {};
        
        Record r(book->m_record.size()+1,book->m_name.c_str(),book->m_id,acc->m_name.c_str(),uid,*p,30,false,tt);
        
        acc->borrowBook(bid,30);
        
        book->m_amout = book->m_amout -1;
        book->addRecord(r);
        BookServiceData n;
        n.save(*book);
        return 0;   
        
    }
    
    return -2;
    
    
   
}    

int BookService::returnBook(unsigned int bid,unsigned int uid)
{
    char acc_path[255] ={};
    sprintf(acc_path,"../data/book/%d.txt",bid); 
    if( -1 == access(acc_path,F_OK))
    {
        return -1;
    }
    BookServiceData m;
    Book* book = m.load(bid);
    AccountData x;
    Account* acc = x.load(uid);
    if(acc == NULL)
    {
        return -1; //
    }
    if(book->m_amout >= book->m_total)
    {
        return -2; //
    }
    vector<Record>::iterator it;
    for(it = book->m_record.begin();it != book->m_record.end();it++)
    {
        if(it->m_perId == uid && false == it->m_isReturn )
        {
            int flag = acc->returnBook(bid);
            if( 0 == flag)
            {
                time_t timep;
                struct tm *p;
                time (&timep);
                p=localtime(&timep);
                book->m_amout = book->m_amout+1;
                it->m_isReturn = true;
                it->m_retTime = *p;
                BookServiceData n;
                n.save(*book);
                return 0;
            }
            if( flag > 0)
            {
                time_t timep;
                struct tm *p;
                time (&timep);
                p=localtime(&timep);
                book->m_amout = book->m_amout+1;
                it->m_isReturn = true;
                it->m_retTime = *p;
                BookServiceData n;
                n.save(*book);
                return flag;
            }      
        } 
    }
    return -3;      
}
bool BookService::recharge_balance (unsigned int uid,unsigned int money)
{
    AccountData x;
    Account* acc = x.load(uid); 
    if(NULL == acc)
    {
        return false;
    }
    acc->m_money = acc->m_money + money;
    AccountData m;
    m.save(*acc);
    delete acc;
    return true;           
}
bool BookService::recharge_deposit (unsigned int uid,unsigned int money)
{
    AccountData x;
    Account* acc = x.load(uid); 
    if(NULL == acc)
    {
        return false;
    }
    acc->m_deposit = acc->m_deposit + money;
    AccountData m;
    m.save(*acc);
    delete acc;
    return true;
}

//查询用户信息：根据用户ID查询用户信息，其中包括用户昵称；注册时间；信用分（初始100，逾期归还将会减-20分，按时归还+10，最高100，低于40将不能借书）；用户借书记录：借书时间，书名、约定归还时间及实际归还时间； 
Account* BookService::queryUser(unsigned int uid) 	
{   
    AccountData x;
    return x.load(uid);
        
}
Book* BookService::queeryBook(unsigned int id)
{
    BookServiceData m;
    return m.load(id);
}
vector<BookInfo> BookService::queeryBook(const char* bookName) 	//查询图书：根据图书ID或图书名查询对应图书信息。
{
    return  BookIndex.findBook(bookName);
}

bool BookService::addBook(Book& book)    	//增加图书：新增图书，自动为图书生成ID。
{
	 BookServiceData m;
	 m.save(book);
	 if( true == BookIndex.addBook(book))
	 {
	    IndexSave();
	    return true;
	 }
	 return false;         
}

bool BookService::delBook(unsigned int id)  		//删除图书：删除图书，只将数量设置为0仍然保留图书其他信息。
{
    char acc_path[255] ={};
    sprintf(acc_path,"../data/book/%d.txt",id); 
    if( -1 == access(acc_path,F_OK))
    {
        return false;
    }
    BookServiceData m;
    Book* book = m.load(id);
    book->m_isShelf = false;
    BookServiceData n;
    n.save(*book);
    return true;    
}

bool BookService::delBookList(unsigned int id)		
{
    char acc_path[255] ={};
    sprintf(acc_path,"../data/booklist/%d.txt",id); 
    if( -1 == access(acc_path,F_OK))
    {
        return false;
    }
    
    if(remove(acc_path) == 0)
    {
        return true;
    }
    else
    {
        perror("remove");
        getchar();
        return false;
    }
}

BookList* BookService::findBookList(unsigned int id)
{
    char acc_path[255] ={};
    sprintf(acc_path,"../data/booklist/%d.txt",id); 
    if( -1 == access(acc_path,F_OK))
    {
        return NULL;
    }
    return BookListLoad(id);    
}

bool BookService::modifyBook(Book* book)
{	
	BookServiceData m;
	m.save(*book);
	delete book;
	return true;
}	

